package com.sxr.signature.sdk.core.imp;

import com.sxr.signature.SignRequest;
import com.sxr.signature.sdk.core.KeyPairDo;
import com.sxr.signature.sdk.core.SignatureService;

import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.Objects;

public class SignatureServiceImp implements SignatureService {
    @Override
    public String generateSignature(SignRequest request) throws Exception {
        Objects.requireNonNull(request);
        String secretKey = request.getSecretKey();
        Objects.requireNonNull(secretKey);
        //
        String data = request.buildStringToSign();
        return sign(data, secretKey);
    }

    // 从 Base64 字符串恢复私钥
    public static PrivateKey base64ToPrivateKey(String base64PrivateKey) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(base64PrivateKey);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory kf = KeyFactory.getInstance("RSA");
        return kf.generatePrivate(keySpec);
    }

    // 签名
    public static String sign(String data, String base64PrivateKey) throws Exception {
        PrivateKey privateKey = base64ToPrivateKey(base64PrivateKey);
        Signature signer = Signature.getInstance("SHA256withRSA");
        signer.initSign(privateKey);
        signer.update(data.getBytes("UTF-8"));
        byte[] signatureBytes = signer.sign();
        return Base64.getEncoder().encodeToString(signatureBytes);
    }


    @Override
    public KeyPairDo generateKeyPair() {
        KeyPairGenerator gen = null;
        try {
            gen = KeyPairGenerator.getInstance("RSA");
        } catch (NoSuchAlgorithmException e) {
            // ignore
            throw new RuntimeException("no such algorithm",e);
        }
        gen.initialize(2048);
        KeyPair keyPair = gen.generateKeyPair();

        // 2. 转为Base64字符串
        String pubStr = publicKeyToBase64(keyPair.getPublic());
        String priStr = privateKeyToBase64(keyPair.getPrivate());
        //
        return new KeyPairDo(pubStr,priStr);
    }


    // 将公钥转为 Base64 字符串
    public static String publicKeyToBase64(PublicKey publicKey) {
        return Base64.getEncoder().encodeToString(publicKey.getEncoded());
    }

    // 将私钥转为 Base64 字符串
    public static String privateKeyToBase64(PrivateKey privateKey) {
        return Base64.getEncoder().encodeToString(privateKey.getEncoded());
    }

}
